package io.github.weiranyi.controller;


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import io.github.weiranyi.feign.ProductFeign;
import io.github.weiranyi.pojo.Product;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/page")
public class PageController {
    @Autowired
    private ProductFeign productFeign;
    /**
     * http://localhost/page/product/query/1
     * http://localhost/page//serverinfo/getport
     *
     * @param id
     * @return
     */
    @RequestMapping("/product/query/{id}")
    public Product findByIdUseResetTemplate(@PathVariable("id") Integer id) {
        return productFeign.query(id);
    }

    // 负载均衡测试
    @RequestMapping("/serverinfo/getport")
    public String getPort() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "结果：" + productFeign.getPort();
    }

    // 豪猪哥-hystrix

    /**
     * - 1.针对熔断处理：hystrix会维护一个线程池，默认大小为10，线程队列默认不起用（默认-1）
     * - 2.由1有：默认所有请求都维护一个线程，请求一多服务就崩了，不能让豪猪哥维护一个线程池
     * - 3.由2有：让每个方法去维护一个线程池
     * - 4.服务者sleep5s，消费者超时设定3s，以下是模拟熔断后得到的响应
     * "timestamp": "2022-10-15T08:11:36.841+0000",
     * "status": 500,
     * "error": "Internal Server Error",
     * "message": "getPortHystrix timed-out and fallback failed.",
     *
     * @return
     */
    @HystrixCommand(
            threadPoolKey = "getPortHystrix", //方法名做为线程池名
            threadPoolProperties = { //维护的一个数组，可以写多个参数
                    @HystrixProperty(name = "coreSize", value = "1"), // 线程池同时能执行线程的个数(并发线程数)
                    @HystrixProperty(name = "maxQueueSize", value = "20") //启用线程队列，最大长度
            },
            commandProperties = { //超时时间的设置
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "15000"), //设置请求超时时间，超过时效就认为服务超时
                    // hystrix高级配置(要求能看懂)
                    //统计时间窗口的设置，默认10s
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"),
                    // 统计时间窗口内的最小请求数
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2"),
                    // 统计时间窗口内的错误数量百分比阈值，50%
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                    // 自我修复时的活动窗口长度，默认5s
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000"),
            }
    )
    @RequestMapping("/serverinfo/getport/hystrix")
    public String getPortHystrix() {
        return "结果：" + productFeign.getPort();
    }

    // 服务降级
    @HystrixCommand(
            commandProperties = { //超时时间的设置
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "9000") //设置请求超时时间，超过时效就认为服务超时
            },
            fallbackMethod = "bottomCoveringMethod" //设置回退方法
    )
    @RequestMapping("/serverinfo/getport/hystrix/downgrade")
    public String getPortHystrixDowngrade() {
        return "结果：" + productFeign.getPort();
    }
    // 兜底方法-返回兜底数据，熔断后触发兜底方法

    /**
     * 1.方法形参和原方法保持一致
     * 2.方法返回值和原方法一致
     *
     * @return
     */
    public String bottomCoveringMethod() {
        return "9701";
    }

}
